<template>
  <div class="navigation-container">
    <div
      v-if="formProps.isShowHeader"
      class="navigation-header"
      @click="handleClickHeader"
      :class="{ border: formProps.border }"
    >
      <slot name="nav-title">
        <div class="navigation-label">
          <div class="common-doc"></div>
          <span>{{ formProps.label || title }}</span>
        </div>
      </slot>
      <div class="navigation-context">
        <slot a="12" name="nav-button"></slot>
        <slot name="prefix" v-bind="self"></slot>
        <el-button
          v-auth
          v-if="formProps.showExportBtn"
          type="primary"
          @click="$emit('exportDataToExcel')"
        >
          <svg-icon icon-class="export" color="white"></svg-icon>
          导出
        </el-button>
        <el-button
          v-if="formProps.showAddBtn"
          type="primary"
          icon="el-icon-circle-plus-outline"
          @click="handleAdd"
          v-auth
          >{{ formProps.addBtnName }}
        </el-button>
        <slot name="suffix" v-bind="self"></slot>
      </div>
    </div>
    <el-collapse-transition v-if="!formProps.hideSearchForm">
      <div v-show="isShowSearch" @click.stop>
        <slot name="content">
          <el-form
            v-if="formProps.formItems.length"
            ref="ruleForm"
            :label-width="formProps.labelWidth"
            :model="modelValue"
            class="navigation-form"
          >
            <el-row type="flex" :gutter="30" style="flex-wrap: wrap">
              <template v-for="(item, index) in formProps.formItems">
                <el-col
                  v-if="formProps.defaultShowCount > index || isExpand"
                  :xs="item.colSpan.xs"
                  :sm="item.colSpan.sm"
                  :md="item.colSpan.md"
                  :lg="item.colSpan.lg"
                  :xl="item.colSpan.xl"
                  :key="item.prop"
                >
                  <el-form-item
                    :label="`${item.label}`"
                    :label-width="`${item.labelWidth}`"
                    :prop="item.prop"
                    v-bind="item.formItemProps"
                  >
                    <CompType
                      :model-value="modelValue"
                      :form-item="item"
                    ></CompType>
                  </el-form-item>
                </el-col>
              </template>
              <el-col
                :md="{ span: 8, offset: calcSubBtnOffset(8) }"
                :xs="{ span: 12, offset: calcSubBtnOffset(12) }"
                :lg="{ span: 8, offset: calcSubBtnOffset(8) }"
                :xl="{ span: 6, offset: calcSubBtnOffset(6) }"
                :sm="24"
                style="display: flex; justify-content: flex-end"
              >
                <el-form-item class="navigation-formbtn">
                  <el-button type="primary" @click="onSubmit">查询</el-button>
                  <el-button
                    v-if="formProps.showRealTime"
                    type="primary"
                    @click="onRealTime"
                    >实时查询</el-button
                  >
                  <el-button @click="reset">重置</el-button>
                  <el-button
                    v-if="
                      formProps.formItems.length > formProps.defaultShowCount
                    "
                    type="text"
                    @click="isExpand = !isExpand"
                  >
                    {{ isExpand ? "收起" : "展开" }}
                    <i
                      :class="
                        isExpand ? 'el-icon-arrow-up' : 'el-icon-arrow-down'
                      "
                    ></i>
                  </el-button>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </slot>
      </div>
    </el-collapse-transition>
    <div class="key-personnel-search" v-if="formProps.showSearchTag">
      <div class="key-personnel-tag">
        <el-tag
          v-for="item in tags"
          :key="item.title"
          :class="`${item.value} ${tagValue === item.value ? 'dark' : ''}`"
          @click="handleTagClick(item)"
        >
          {{ item.title }}
        </el-tag>
      </div>
      <el-radio-group v-model="searchValue" @change="handleSearch">
        <el-radio-button
          v-for="item in sicknessTags"
          :key="item.icon"
          :label="item.value"
        >
          <SvgIcon :icon-class="item.icon" style="margin-right: 3px"></SvgIcon>
          {{ item.title }}
        </el-radio-button>
      </el-radio-group>
    </div>
  </div>
</template>
<script>
import CompType from "./compType";
import { getDict } from "@/utils/dictionary";
import { tags, sicknessTags } from "@/utils/common";
import moment from "moment";

export default {
  inheritAttrs: false,
  components: { CompType },
  props: {
    title: String,
    navProps: {
      type: Object,
      default: () => ({}),
    },
    columns: {
      type: Array,
      default: () => [],
    },
    defaultOpenSearch: {
      // 是否默认展开搜索
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      self: this,
      modelValue: {}, // 表单的值
      isExpand: false, // 是否展开所有表单项
      isShowSearch: this.defaultOpenSearch,
      searchValue: "all",
      tagValue: "all",
      cacheQueryParams: {}, // 用来保存 点击 查询后 的参数
      sicknessTags,
      tags,
      formProps: {
        label: "",
        addBtnName: "新增",
        showSearchTag: false,
        isShowHeader: true, // 是否显示导航头
        defaultShowCount: 2, // 默认展示表单项个数
        showAddBtn: true,
        showRealTime: false, //是否展示实时查询
        showExportBtn: false,
        showSearchBtn: true,
        openSearchWithClickHeader: false, // 点击导航条的时候切换搜索表单
        formItems: [],
        labelWidth: "75px",
        hideSearchForm: false, // 隐藏搜索表单
        border: true,
        ...this.navProps,
      },
    };
  },
  watch: {
    columns: {
      handler: "formatFormItems",
      immediate: true,
    },
    navProps(val) {
      this.formProps = {
        ...this.formProps,
        ...val,
      };
    },
  },
  computed: {
    getModelValue() {
      const filterValues = [undefined, null, ""];
      const params = {};
      if (this.searchValue !== "all") {
        params[this.searchValue] = true;
      }
      if (this.tagValue !== "all") {
        params[this.tagValue] = true;
      }
      return Object.keys(this.modelValue)
        .filter((key) => !filterValues.includes(this.modelValue[key]))
        .reduce((prev, currKey) => {
          const formItem = this.formProps.formItems.find(
            (i) => i.prop === currKey
          );
          const timeStr = [" 00:00:00", " 23:59:59"];
          if (formItem?.formItemProps?.isTimeParams) {
            if (this.modelValue[currKey][0] && this.modelValue[currKey][1]) {
              const startTime =
                formItem?.formItemProps?.timeParamsProps?.startTime ??
                "startTime";
              const endTime =
                formItem?.formItemProps?.timeParamsProps?.endTime ?? "endTime";
              prev[currKey] = {};
              prev[currKey][startTime] =
                this.modelValue[currKey][0] + timeStr[0];
              prev[currKey][endTime] = this.modelValue[currKey][1] + timeStr[1];
            }
          } else {
            prev[currKey] = this.modelValue[currKey];
          }

          return prev;
        }, params);
    },
    dictionaryMap() {
      return this.$store.getters["dictionary/getDictionary"];
    },
  },
  methods: {
    calcSubBtnOffset(span) {
      const total =
        (this.isExpand
          ? this.formProps.formItems.length
          : this.formProps.defaultShowCount) * span;
      const remainder = total % 24;
      if (total < 24) {
        return 0;
      } else if (remainder === 0) {
        return 24 - span;
      }
      return 24 - remainder - span;
    },
    formatFormItems() {
      this.formProps.formItems = this.columns
        .filter((item) => !item.hideInSearch && item.prop)
        .map((item) => {
          const formItemProps = item.formItemProps || {};
          const formItem = {
            ...item,
            label: formItemProps?.label || item.label || "默认",
            prop:
              item.searchField ||
              formItemProps.prop ||
              item.prop.split(".").at(-1) ||
              "",
            labelWidth: formItemProps.labelWidth,
            disabled: formItemProps.disabled || false,
            defaultValue: item.defaultValue,
            colSpan: {
              xs: formItemProps?.colSpan?.xs ?? 12,
              sm: formItemProps?.colSpan?.sm ?? 12,
              md: formItemProps?.colSpan?.md ?? 12,
              lg: formItemProps?.colSpan?.lg ?? 8,
              xl: formItemProps?.colSpan?.xl ?? 6,
            },
          };

          // 表单联动
          if (Array.isArray(formItemProps?.watch?.target)) {
            formItemProps?.watch?.target.forEach((item) => {
              this.$watch(`modelValue.${item}`, (value) => {
                const targetItem = this.formProps.formItems.find(
                  (n) => n.prop === item
                );
                const values = {
                  targetItem, // 目标FormItem
                  targetValue: value, // 目标值
                  currentItem: formItemProps, // 当前FormItem
                  modelValue: this.modelValue, // 表单的数据
                  formItems: this.formProps.formItems, // 当前所有表单项
                  columns: this.columns, // 表格列配置
                };
                formItemProps?.watch?.callback(values);
              });
            });
          }

          // 如果是字典类型
          if (item.dictType) {
            this.dictionaryMap[item.dictType] || getDict([item.dictType]);
            const unwatch = this.$watch(
              `dictionaryMap.${item.dictType}`,
              () => {
                this.$set(
                  formItemProps,
                  "dataSource",
                  this.dictionaryMap[item.dictType]
                );
                if (unwatch) unwatch();
              },
              { immediate: true }
            );
          }

          if (typeof formItemProps?.request === "function") {
            // 异步请求数据
            ~(async () => {
              const data = await formItemProps.request({
                modelValue: this.modelValue,
              });
              this.$set(formItemProps, "dataSource", data);
            })();
          }
          return formItem;
        })
        .sort((a, b) => a.searchOrder - b.searchOrder);
      this.modelValue = this.formProps.formItems.reduce((prev, curr) => {
        prev[curr.prop] = curr.defaultValue;
        return prev;
      }, {});
    },
    reset() {
      this.$emit("reset"); // 给表单重置事件
      setTimeout(() => {
        this.$refs.ruleForm.resetFields();
        // this.modelValue = {};
        this.onSubmit();
      });
    },
    resetFields() {
      console.log(this.modelValue);
      // debugger;
      this.$refs.ruleForm.resetFields();

      this.$nextTick(() => {});
    },
    handleAdd() {
      this.$emit("add");
    },
    handleClickHeader() {
      if (this.formProps.openSearchWithClickHeader) {
        this.isShowSearch = !this.isShowSearch;
      }
    },
    handleTagClick(item) {
      this.tagValue = item.value;
      this.onSubmit();
    },
    handleSearch() {
      this.onSubmit();
    },
    // getParams() {
    //   this.$emit("getParams", this.getModelValue);
    // },
    // 获取表单参数并触发表格刷新
    onSubmit() {
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          this.cacheQueryParams = this.getModelValue;
          this.$emit("query", this.getModelValue);
        } else {
          return false;
        }
      });
    },
    onRealTime() {
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          this.cacheQueryParams = this.getModelValue;
          this.$emit("query", {
            ...this.getModelValue,
            statisticDate: moment().format("YYYY-MM-DD"),
          });
        } else {
          return false;
        }
      });
    },
  },
};
</script>
<style lang="scss" scope>
@import "~@/style/common.scss";

.navigation-container {
  .navigation-header {
    height: 50px;
    background: #f3f3f3;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 15px;

    &.border {
      border: 1px solid rgba(228, 228, 228, 1);
    }

    .el-tabs {
      align-self: flex-end;

      .el-tabs__header {
        margin: 0;
      }

      .el-tabs__item.is-active {
        background-color: white;
      }
    }

    .navigation-label {
      display: flex;
      font-size: 16px;
      color: rgb(102, 100, 100);
    }

    .navigation-context {
      display: flex;

      .navigation-search-button {
        margin-left: 5px;
      }
    }
  }

  .navigation-form {
    margin: 15px auto 0;
    width: 90% !important;
    .el-form-item {
      margin-right: 20px;
      white-space: nowrap;
      margin-bottom: 12px;
    }
    .el-form-item__content {
      display: flex;
      align-items: center;
      height: 40px;
    }
    .navigation-formbtn {
      margin-left: 20px;
    }
  }

  .key-personnel-search {
    display: flex;
    flex-direction: column;
    align-items: flex-end;

    .key-personnel-tag {
      margin-bottom: 15px;

      span {
        margin: 0 5px;
        cursor: pointer;
      }
    }
  }
}
</style>
